#ifndef LINAPI_INCLUDED

//#define _GNU_SOURCE
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>

#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>


#include <dirent.h>
#include <utime.h>
#include <stdlib.h>
#include <sys/times.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>


#define LINUX

void initLinuxApi();

#define initApi() initLinuxApi();

#define FSLASH '/'
#define SLASH '\\'
#define CONSOLE "/dev/stdout"
#define TIME_T long
#define ioctlsocket ioctl
extern int timez;
#define timeLocal (time(NULL)-timez)

#define ULONG unsigned long
#define UCHAR unsigned char
#define USHORT unsigned short
#define BYTE unsigned char
#define INVALID_HANDLE -1
#define INFINITE 0xffffffff
#define sock_errno() errno

/* File Functions */

                /*file open actions*/

#define ACTION_OPEN_IF_EXISTS 0
#define ACTION_CREATE_NEW O_CREAT|O_EXCL
#define ACTION_TRUNCATE_EXISTING        O_TRUNC

                /*file access modes */
#define FILE_ACCESS_READONLY O_RDONLY
#define FILE_ACCESS_WRITEONLY O_WRONLY
#ifdef READ_ONLY
#define FILE_ACCESS_READWRITE   O_RDONLY
#else
#define FILE_ACCESS_READWRITE   O_RDWR
#endif
#define FILE_ACCESS_NONE        O_RDONLY
             /*file share modes */

#define FILE_SHARE_READONLY     0
#define FILE_SHARE_WRITEONLY 0
#define FILE_SHARE_NONE 0
#define FILE_SHARE_ALL 0

                /* open flags */

#define ACCESS_FLAGS_RANDOM 0
//#define ACCESS_FLAGS_SYNCWRITE O_SYNC
#define ACCESS_FLAGS_SEQUENTIAL 0
#define ACCESS_FLAGS_NORMAL 0
             /* create flags */
#define ATTRIBUTE_NORMAL S_IRWXU | S_IRWXG | S_IRWXO
#define INVALID_FILE_POINTER -1


#define HFILE int
#define FROM_BEGINNING SEEK_SET
#define FROM_END        SEEK_END
#define FROM_CURRENT    SEEK_CUR

#define FlushFile(handle) fsync(handle)
#define FileRead(handle,buff,bytestoread,bytesread,success) success=((int)(bytesread=::read(handle,buff,bytestoread))!=-1)
#define FileWrite(handle,buff,bytestowrite,byteswritten,success) success=((int)(byteswritten=::write(handle,buff,bytestowrite))!=-1)

#define FileClose(handle,success) ::close(handle);success=1;
#define FinderClose(handle) ::closedir(handle)
int memicmp(char*,char*,int);

#define HDIR DIR*
#define NULLHDIR NULL
#define FILEFINDBUF struct stat*

#define FILEONLY S_IFREG
#define DIREONLY S_IFDIR
#define FILEANY  S_IFDIR|S_IFREG
#define strnicmp strncasecmp
#define stricmp strcasecmp
#define filenamecmp strcmp
#define PipeCreate(h1,h2,psize,success) int hds[2];  if(pipe(hds)!=-1){  h1=hds[0];  h2=hds[1];  success=1; }else success=0;

//#define FileDelete(fname,success) success=((unlink(fname)==-1)?(errno==ENOENT):1);
#define FileDelete(fname,success) if(unlink(fname)==-1) success=(errno==ENOENT);else success=1;
#define FileLock(handle,success) success=!flock(handle,LOCK_EX);
#define FileOpen(filename,handle,action,accessmode,sharemode,openmode,attributes,success)  success=((handle=::open(filename,accessmode|sharemode|action,openmode|attributes))!=INVALID_HANDLE);if ((handle==STDOUT_FILENO)||(handle==STDERR_FILENO)){ int dh=dup(handle);::close(handle);handle=dh;}
#define FileSeek(handle,offset,from,newptr,success) success=((int)(newptr=lseek(handle,offset,from))!=INVALID_FILE_POINTER)
#define FileMove(fname,newname,success) success=::rename(fname,newname)==0;

#define GetFileTimeLastWrite(handle,t)   struct stat buf;  fstat(handle,&buf);  t=buf.st_mtime-timez;
#define SetFileTimeLastWrite(filename,handle,t,success) struct utimbuf ut; ut.actime=t+timez;ut.modtime=t+timez;success=(utime(filename,&ut)==0);
#define SetMaxHandles(a,success) ;
#define setAttribute(handle,value) ;
#define DirectoryCreate(path,success) success=(mkdir(path,0777)==0);
//#define DirectoryDelete(path,success) success=((rmdir(path)==-1)?(errno==ENOENT):1);
#define DirectoryDelete(path,success) if (rmdir(path)==-1) success=(errno==ENOENT); else success=1;

/* processes and threads*/
//S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP  | S_IROTH | S_IXOTH | S_IWOTH

#define HEV sem_t*
#define HMTX pthread_mutex_t*


extern HMTX TSmtx;
extern HMTX CSmtx;

//#define EnterMemSec() pthread_mutex_lock(TSmtx);
//#define ExitMemSec() pthread_mutex_unlock(TSmtx);
#define EnterMemSec()
#define ExitMemSec()

#define EnterCritSec() pthread_mutex_lock(CSmtx);
#define ExitCritSec() pthread_mutex_unlock(CSmtx);

#define EnterMustComplete() ;
#define ExitMustComplete() ;


void setClock(sem_t*,ULONG);
void clearClock(sem_t*);

void postEvents();
#define makeEventSem(hevent,success)	if (hevent==0) {EnterMemSec(); hevent=(sem_t*) new char[sizeof(sem_t)];ExitMemSec()}; success=(sem_init(hevent, 0, 0L)==0);
#define PostEventSem(hwait)    sem_post(hwait)
#define WaitEventSem(hevent,dwMilSec,success) setClock(hevent,dwMilSec);success=(sem_wait(hevent)==0);clearClock(hevent);
#define CloseEventSem(hevent)   sem_destroy(hevent);delete hevent;hevent=0;
#define ResetEventSem(x) sem_init(x, 0, 0L)

extern  pthread_mutexattr_t mutant;
#define makeMutexSem(hmtx,success) EnterMemSec();hmtx=(pthread_mutex_t*) new char[sizeof(pthread_mutex_t)];ExitMemSec(); success=(pthread_mutex_init(hmtx,&mutant)==0);
#define RequestMutexSem(hmtx,dwMilSec)        pthread_mutex_lock(hmtx);
#define ReleaseMutexSem(hmtx)        pthread_mutex_unlock(hmtx);
#define CloseMutexSem(hmtx) pthread_mutex_destroy(hmtx); delete hmtx;hmtx=0;







extern  pthread_attr_t that;
#define TID pthread_t
#define THREADFN void* 
#define EXIT_THREAD_FN return 0;

#define ThreadCreate(thandle,threadFunc,pRunnable,stackSize,success) success=!pthread_create(&thandle,&that,threadFunc,pRunnable); 
#define FreeThreadResources(thandle)  
#define KillThread(thandle)     pthread_cancel(thandle)

#define getProcessId(pid,success) success=(pid=getpid()!=0)
#define SetPriorityServer()  ;
#define SetCurrentThreadPriorityHighest() ; 
#define SetThreadPriorityHighest(tid) ; 
#define SetThreadPriorityLowest(tid) ;  


#define SleepMilSec(n) usleep(n*1000)
#define GetClockTicks() GetTickCount()



/*
to be discarded
#define ExecuteProgram(prgname,cars,returncode,success,fo) \
 int an=-1;\
 int er=-1;\
 int fd=-1;\
 int fe=-1;\
 if (fo) {\
     fo->close();\
     an=dup(STDOUT_FILENO);\
     ::close(STDOUT_FILENO);\
     fd=::open(fo->getName(),O_RDWR);\
 }\
 success=0;\
 if (fd==STDOUT_FILENO){\
  er=dup(STDERR_FILENO);\
  ::close(STDERR_FILENO);\
  fe=dup(fd);\
  char *ppars[16]; \
  int cc=0; \
  int q=0;  \
  int k=1; \
  ppars[0]=prgname; \
  for(char* prs=cars+1;*prs!=0 && (k<16);prs++){ \
    if(*prs=='"'){ \
      if(q==0){ \
        ppars[k++]=prs+1; \
        q=1; \
      }else{ \
        *prs=0; \
        q=0;  \
      } \
    }else{  \
     if(q==0){   \
       if(*prs==' '){ \
  	if(cc){	 \
         *prs=0;   \
         cc=0; \
        } \
       }else{ \
        if(cc==0){ \
         ppars[k++]=prs; \
        } \
        cc++; \
       } \
     } \
    } \
  } \
  ppars[k]=NULL; \
  int ppid=fork(); \
  if (ppid==0){  \
   
   execv(prgname,ppars); \
   exit(255); \
  }else{  \
    if(waitpid(ppid,&k,0)==ppid){  \
     if(k!=0)   \
      returncode=WEXITSTATUS(k); \
     if(returncode!=255)  \
      success=1; \
    } \
  }\
 }\
 if(fo){\
    ::close(fd);\
    ::dup(an);\
    ::close(fe);\
    if(fe==STDERR_FILENO){\
     ::dup(er);\
    }\
    ::close(er);\
    ::close(an);\
 }\
*/



#define ExecuteProgram(prgname,cars,returncode,success,fo) \
  success=0;\
  char *ppars[32]; \
  int cc=0; \
  int q=0;  \
  int k=1; \
  ppars[0]=prgname; \
  for(char* prs=cars+1;*prs!=0 && (k<32);prs++){ \
    if(*prs=='"'){ \
      if(q==0){ \
        ppars[k++]=prs+1; \
        q=1; \
      }else{ \
        *prs=0; \
        q=0;  \
      } \
    }else{  \
     if(q==0){   \
       if(*prs==' '){ \
  	if(cc){	 \
         *prs=0;   \
         cc=0; \
        } \
       }else{ \
        if(cc==0){ \
         ppars[k++]=prs; \
        } \
        cc++; \
       } \
     } \
    } \
  } \
  ppars[k]=NULL; \
  int fd=fo->getHandle();\
  int ppid=fork();\
  if (ppid==0){  \
   ::close(STDOUT_FILENO);\
   dup(fd);\
   ::close(STDERR_FILENO);\
   dup(fd);\
   execv(prgname,ppars); \
   exit(255); \
  }else{  \
    if(waitpid(ppid,&k,0)==ppid){\
	 fo->close();\
     if(k!=0)\
      returncode=WEXITSTATUS(k);\
     if(returncode!=255)  \
      success=1; \
    }\
  }\



#define SetDateTime(t) time_t x=t;stime(&x);
//TCPIP
#define soclose(n) close(n)
#define so_cancel(n) close(n)
#define GetTickCount()  times(NULL);
#define LINAPI_INCLUDED
#endif
